﻿// ===================================
// <copyright>
// This file is part of LABSMFController.
//
//    LABSMFController is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    LABSMFController is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with LABSMFController.  If not, see <http://www.gnu.org/licenses/>.
//    Copyright 2011 David Bakker
//
//</copyright>
// <author>David Bakker</author>
// <email>mailto:DavidFBakker@gmail.com</email>
// <created>Saturday, May 07, 2011</created>
// <lastedit>Saturday, May 07, 2011</lastedit>
// ===================================


using System;
using System.Threading;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Hardware;
using LABSMFController.LABS;
using LABSMFController.LABS.Classses;
using LABSMFController.LABS.Devices;
using LABSMFController.LABS.Services;
using LABSMFController.UI;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Input;
using Microsoft.SPOT.Net.NetworkInformation;
using Microsoft.SPOT.Presentation;
using BeerDevices = LABSMFController.LABS.Devices.BeerDevices;

namespace LABSMFController
{
    public class Program : Application
    {
        private static Program _myApplication;

        private static FEZ_Components.Button _downButton;
        private static FEZ_Components.Button _resetButton;

        public static void Main()
        {
                                
            BeerProgram.Initialize();
            BeerDevices.ResetDevices();

            //var logThread = new Thread(LogThreadFunction);
            //logThread.Start();

            SetupLCD();
            Cpu.GlitchFilterTime = new TimeSpan(0, 0, 0, 0, 300); //300ms


            // SDCard.Init();

            EventHandlers.PanicTriggerEvent += BeerDevicesPanicTriggerEvent;

            SetupNetwork();

            _downButton = new FEZ_Components.Button(FEZ_Pin.Interrupt.ButtonDown);
            _downButton.ButtonPressEvent += DownButtonButtonPressEvent;

            _resetButton = new FEZ_Components.Button(FEZ_Pin.Interrupt.ButtonUp);
            _resetButton.ButtonPressEvent += ResetButtonButtonPressEvent;

            // var svcThread = new Thread(StartSVC);
            //svcThread.Start();

            //var gcThread = new Thread(GCThread);
            //gcThread.Start();

            var csThread = new Thread(ClientSocketThread);
            csThread.Start();

            _myApplication = new Program();
            // Window mainWindow = _myApplication.CreateWindow();

            var main = new origMainWindow();
            Buttons.Focus(main);
            //// Initialize Touch Interface
            // Touch.Initialize(_myApplication);
            //TouchCollectorConfiguration.CollectionMethod = CollectionMethod.Native;
            // TouchCollectorConfiguration.CollectionMode = CollectionMode.InkOnly;
            // TouchCollectorConfiguration.TouchMoveFrequency = 10;

            // Create the object that configures the GPIO pins to buttons.
            //var inputProvider = new GPIOButtonInputProvider(null);

            
            BeerProgram.Start();

            // BeerProgram.EnableDebug = true;

            // Start the application
            _myApplication.Run(main);
        }

        public Window CreateWindow()
        {
            var main = new MainWindow();
            return main.CreateWindow();
        }

        private static void ResetButtonButtonPressEvent(FEZ_Pin.Interrupt pin, FEZ_Components.Button.ButtonState state)
        {
            BeerDevices.ResetDevices();
        }

        private static void DownButtonButtonPressEvent(FEZ_Pin.Interrupt pin, FEZ_Components.Button.ButtonState state)
        {
            for (int c = 0; c < BubblerServiceClass.MAXBubblers; c++)
            {
                BeerProgram.ResetLevel(c);
            }

            for (int c = 0; c < TemperatureServiceClass.MAXProbes; c++)
            {
                BeerProgram.ResetTemps(c);
            }
        }

        private static void StartSVC()
        {
            //SVC.StartSVC();            
        }

        private static void SetupLCD()
        {
            Configuration.LCD.SetRotation(Configuration.LCD.Rotation.Rotate_180);
            var lcdConfig = new Configuration.LCD.Configurations
                                {
                                    Width = 320,
                                    Height = 240,
                                    PriorityEnable = false,
                                    OutputEnableIsFixed = true,
                                    OutputEnablePolarity = true,
                                    HorizontalSyncPolarity = false,
                                    VerticalSyncPolarity = false,
                                    PixelPolarity = true,
                                    HorizontalSyncPulseWidth = 41,
                                    HorizontalBackPorch = 27,
                                    HorizontalFrontPorch = 51,
                                    VerticalSyncPulseWidth = 10,
                                    VerticalBackPorch = 8,
                                    VerticalFrontPorch = 16,
                                    PixelClockDivider = 8
                                };

            // Only use if needed, see documentation.

            // Set config
            Configuration.LCD.Set(lcdConfig);
        }

        private static void DoDHCP()
        {
            NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
            if (!interfaces[0].IsDhcpEnabled)
            {
                interfaces[0].EnableDhcp();
            }
            else
            {
                interfaces[0].RenewDhcpLease();
            }

            BeerProgram.Log(interfaces[0].IPAddress);

            for (int i = 0; i < interfaces[0].DnsAddresses.Length; i++)
            {
                BeerProgram.Log("DNS Server " + i + ": " + interfaces[0].DnsAddresses[i]);
            }
        }

        private static void SetupNetwork()
        {
            try
            {
                NetworkInterface ni = NetworkInterface.GetAllNetworkInterfaces()[0];

                ni.EnableStaticIP(Settings.GetSetting("IPAddress"), Settings.GetSetting("Subnet"),
                                  Settings.GetSetting("GateWay"));
                ni.EnableStaticDns(Settings.DNSServers);
                BeerProgram.Log("Started IP on " + Settings.GetSetting("IPAddress"));
            }
            catch (Exception ex)
            {
                throw new ApplicationException(ex.Message);
            }
        }

        private static void LogThreadFunction()
        {
            while (true)
            {
                BeerProgram.Log("BK Temp " + BeerProgram.GetTemp(Location.BK) + " | MLT Temp " +
                                BeerProgram.GetTemp(Location.MLT) + " | HLT Temp " +
                                BeerProgram.GetTemp(Location.HLT));

                BeerProgram.Log("BK Level " + BeerProgram.GetLevel(Location.BK) + " | MLT Level " +
                                BeerProgram.GetLevel(Location.MLT) + " | HLT Level " +
                                BeerProgram.GetLevel(Location.HLT));

                for (int c = 0; c < BubblerServiceClass.MAXBubblers; c++)
                {
                    BeerProgram.Log(Location.Names[c] + " Level " + BeerProgram.GetLevel(c) + " | Low " +
                                    BeerProgram.GetLowLevel(c) + " | High " + BeerProgram.GetHighLevel(c));
                }
                Thread.Sleep(1000);
            }
        }

        private static void BeerDevicesPanicTriggerEvent(TriggerMessage panicMessage)
        {
            throw new ApplicationException(panicMessage.Message);
        }

        private static void ClientSocketThread()
        {
            while (true)
            {                
                BeerProgram.SendToClients(BeerProgram.GetClientOutPut(typeof (TempProbe)));
                BeerProgram.SendToClients(BeerProgram.GetClientOutPut(typeof (BubblerDevice)));
                BeerProgram.SendToClients(BeerProgram.GetClientOutPut(typeof(HeaterDevice)));
                BeerProgram.SendToClients(BeerProgram.GetClientOutPut(typeof(PumpDevice)));
                BeerProgram.SendToClients(BeerProgram.GetClientOutPut(typeof(PWMValveDevice)));
                BeerProgram.SendToClients(BeerProgram.GetClientOutPut(typeof(QueueServiceClass)));

                //Need to do liquids
                //BeerProgram.SendToClients(BeerDevices.GetStepsClientOutPut());

                BeerProgram.SendToClients(ValveDevices.GetValvesClientOutPut());

                BeerProgram.SendToClients(Settings.GetSettingsClientOutPut());
 
 
                BeerProgram.SendToClients(Location.GetLocationClientOutPut());
                BeerProgram.SendToClients(VValveDevices.GetVValvesClientOutPut());
                BeerProgram.SendToClients(BeerProgram.GetAllLogs());
                Thread.Sleep(2*1000);
            }
        }

        private static void GCThread()
        {
            while (true)
            {
                Debug.GC(true);

                Thread.Sleep(5*60*1000);
            }
        }

        public static void AnalogThreadFunction()
        {
            //var batteryVoltage = new AnalogIn((AnalogIn.Pin) FEZ_Pin.AnalogIn.AD6);
            //batteryVoltage.SetLinearScale(0, 3300);
            //while (true)
            //{
            //    var voltage = batteryVoltage.Read();
            //  //  BeerProgram.Log("Voltage " + voltage);
            //    Thread.Sleep(500);
            //}
        }
    }
}